let logger = require("pomelo-logger").getLogger(__filename);
let COMPONENT_NAME = "mailComponent";
let pomelo = require("pomelo");
let mailCreator = require("../../mail").create;
let DateUtil = require("../../../../utils/dateUtil");

const userMailMaxSize = 40;

function MailComponent(owner) {
    this.owner = owner;
    this.mails = {};
    this.maxReceivedMailTime = 0;
}

MailComponent.prototype.login = function() {
    this.receiveMails();
    this.removeExpiredMails();
    this.ensureMailCapability(userMailMaxSize);
};

MailComponent.prototype.getCountOfMail = function () {
    let count = 0;
    for (let mail of this.mails) {
        count = count + 1;
    }
    return count;
};

MailComponent.prototype.receiveMails = function () {
    let now = DateUtil.nowMS();
    let mailDataService = pomelo.app.get("mailDataService");
    let unReceivedMailDatas = mailDataService.getUnReceivedMailDatas(this.owner.getUid(),
        this.maxReceivedMailTime);
    for (let mailData of unReceivedMailDatas) {
        let mail = mailCreator(mailData, true, 0);
        if (!this.mails.hasOwnProperty(mail.getId())) {
            this.mails[mail.getId()] = mail;
        }
    }
    this.maxReceivedMailTime = now;
};

MailComponent.prototype.removeExpiredMails = function () {
    let now = DateUtil.nowMS();
    let idToRemoved = [];
    for (let key in this.mails) {
        let mail = this.mails[key];
        if (now - mail.getSenderTime() >= 24 * 7 * 3600 * 1000) {
            idToRemoved.push(key);
        }
    }
    for (let id in idToRemoved) {
        delete this.mails[id];
    }
};

MailComponent.prototype.ensureMailCapability = function (max) {
    let mailList = [];
    for (let key in this.mails) {
        let mail = this.mails[key];
        mailList.push(mail);
    }
    mailList.sort(function (m1, m2) {
        if (m1.getSenderTime() > m2.getSenderTime()) {
            return -1;
        } else if (m1.getSenderTime() === m2.getSenderTime()) {
            return 0;
        } else {
            return 1;
        }
    });
    mailList = mailList.slice(0, max);
    this.mails = {};
    for (let mail of mailList) {
        this.mails[mail.getId()] = mail;
    }
};

MailComponent.prototype.logout = function(){

};

MailComponent.prototype.contain = function (id) {
    return this.mails.hasOwnProperty(id);
};

MailComponent.prototype.sendMail = function(mailData) {
    if (this.mails.hasOwnProperty(mailData.getId())) {
        logger.error("add duplicate id mail");
        return false;
    }
    let mail = mailCreator(mailData, true, 0);
    this.mails[mail.getId()] = mail;
    this.maxReceivedMailTime = DateUtil.nowMS();
    this.ensureMailCapability(userMailMaxSize);
    return true;
};

MailComponent.prototype.deleteMail = function (id) {
    if (this.mails.hasOwnProperty(id)) {
        let mail = this.mails[id];
        if (mail.getIsNew()) {
            logger.error("can not delete new mail. mailId=" + id + " playerId=" + this.owner.getUid());
            return null;
        }
        /*
        if (mail.hasAward()) {
            logger.error("can not delete award mail. mailId=" + id + " playerId=" + this.owner.getUid());
            return null;
        }
        */
        delete this.mails[id];
        return mail;
    } else {
        logger.error("delete not existed mail. mailId=" + id + " playerId=" + this.owner.getUid());
        return null;
    }
};

MailComponent.prototype.readMail = function (id) {
    if (this.mails.hasOwnProperty(id)) {
        let mail = this.mails[id];
        if (mail.readOrClaim(this.owner)) {
            delete this.mails[mail.getId()];
        }
        return mail;
    } else {
        logger.error("read not existed mail. mailId=" + id + " playerId=" + this.owner.getUid());
        return null;
    }
};

MailComponent.prototype.readAllMails = function () {
    let claimedMails = [];
    for (let key in this.mails) {
        let mail = this.mails[key];
        if (mail.hasAward()) {
            mail.readOrClaim(this.owner);
            claimedMails.push(mail);
        }
   }
   for (let mail of claimedMails) {
        delete this.mails[mail.getId()];
   }
   return claimedMails;
};


MailComponent.prototype.findById = function (mailId) {
    if (this.mails.hasOwnProperty(mailId)) {
        return this.mails[mailId];
    }else{
        return null;
    }
};

MailComponent.prototype.fromBSON = function (document) {
    if (!document.hasOwnProperty(COMPONENT_NAME)) {
        logger.error("load mailComponent failed. document=" + JSON.stringify(document));
        this.maxReceivedMailTime = 0;
        this.mails = {};
        return;
    }
    let node = document[COMPONENT_NAME];
    this.maxReceivedMailTime = node["maxReceivedMailTime"];
    let mailsNodes = node["mails"];
    for (let mailNode of mailsNodes) {
        let mailId = mailNode["id"];
        let isNew = mailNode["isNew"];
        let readTime = mailNode["readTime"];
        let mailData = pomelo.app.get("mailDataService").findById(mailId);
        if (!!mailData) {
            let mail = mailCreator(mailData, isNew, readTime);
            this.mails[mail.getId()] = mail;
        } else {
            logger.error("invalid mailData id = " + mailId + " playerId=" + this.owner.getUid());
        }
    }
};

MailComponent.prototype.buildBSON = function (document) {
    let mailNodes = [];
    for (let key in this.mails) {
        let mail = this.mails[key];
        mailNodes.push({
            id : mail.getId(),
            isNew : mail.getIsNew(),
            readTime : mail.getReadTime()
        });
    }
    document[COMPONENT_NAME] = {
        maxReceivedMailTime : this.maxReceivedMailTime,
        mails : mailNodes
    };
};

MailComponent.prototype.toJSON = function () {
   let result = [];
    for (let key in this.mails) {
        let mail = this.mails[key];
       result.push(mail.toJSON());
   }
   return result;
};

module.exports.create = function (owner) {
    return new MailComponent(owner);
};

